package com.finance.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.finance.entity.GoodsInOut;
import com.finance.mapper.GoodsInOutMapper;
import com.finance.service.GoodsInOutService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * C08
 * 商品出入库数据Service实现类
 */
@Slf4j
@Service
public class GoodsInOutServiceImpl extends ServiceImpl<GoodsInOutMapper, GoodsInOut> implements GoodsInOutService {

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int processOrders(List<Map<String, String>> records) {
        return processOrders(records, null, false, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int processOrders(List<Map<String, String>> records, String searchDate, boolean forceUpdate) {
        return processOrders(records, searchDate, forceUpdate, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int processOrders(List<Map<String, String>> records, String searchDate, boolean forceUpdate, String cinemaId) {
        // 1. 参数校验
        if (records == null || records.isEmpty()) {
            log.warn("No records to process for C08 data");
            return 0;
        }

        // 2. 检查数据是否已存在
        if (!forceUpdate && searchDate != null) {
            long count = lambdaQuery()
                .eq(GoodsInOut::getSearchDate, searchDate)
                .eq(GoodsInOut::getCinemaId, cinemaId)
                .count();
            if (count > 0) {
                log.info("C08 data for date {} and cinemaId {} already exists and forceUpdate is false, skipping", searchDate, cinemaId);
                return 0;
            }
        }

        // 3. 如果强制更新，先删除指定日期的数据
        if (forceUpdate && searchDate != null) {
            lambdaUpdate()
                .eq(GoodsInOut::getSearchDate, searchDate)
                .eq(GoodsInOut::getCinemaId, cinemaId)
                .remove();
            log.info("Deleted existing C08 data for date {} and cinemaId {} due to forceUpdate", searchDate, cinemaId);
        }

        // 4. 处理数据
        List<GoodsInOut> inOutList = new ArrayList<>();
        for (Map<String, String> record : records) {
            try {
                //影院名称,影院编码,采购单编码,入库单编码,入库时间,入库类型,采购类型,货品名称,货品编码,货品类型
                GoodsInOut inOut = new GoodsInOut();
                if (StringUtils.hasText(record.get("影院名称"))) {
                    inOut.setCinemaName(record.get("影院名称"));
                }
                if (StringUtils.hasText(record.get("影院编码"))) {
                    inOut.setCinemaCode(record.get("影院编码"));
                }
                inOut.setCinemaId(cinemaId);
                if (StringUtils.hasText(record.get("采购单编码"))) {
                    inOut.setPurchaseOrderCode(record.get("采购单编码"));
                }
                if (StringUtils.hasText(record.get("入库单编码"))) {
                    inOut.setInOrderCode(record.get("入库单编码"));
                }
                
                // 处理入库时间
                String inTimeStr = record.get("入库时间");
                if (StringUtils.hasText(inTimeStr)) {
                    try {
                        inOut.setInTime(LocalDateTime.parse(inTimeStr, DATE_TIME_FORMATTER));
                    } catch (Exception e) {
                        log.warn("Invalid in time format: {}", inTimeStr);
                    }
                }
                
                if (StringUtils.hasText(record.get("入库类型"))) {
                    inOut.setInType(record.get("入库类型"));
                }
                if (StringUtils.hasText(record.get("采购类型"))) {
                    inOut.setPurchaseType(record.get("采购类型"));
                }
                if (StringUtils.hasText(record.get("货品名称"))) {
                    inOut.setGoodsName(record.get("货品名称"));
                }
                if (StringUtils.hasText(record.get("货品编码"))) {
                    inOut.setGoodsCode(record.get("货品编码"));
                }
                if (StringUtils.hasText(record.get("货品类型"))) {
                    inOut.setGoodsType(record.get("货品类型"));
                }
                // 大类,入库数量,计量单位,入库含税金额,入库不含税金额,总税额,含税单价,不含税单价,税额,进货税率,供应商
                if (StringUtils.hasText(record.get("大类"))) {
                    inOut.setCategory(record.get("大类"));
                }
                if (StringUtils.hasText(record.get("计量单位"))) {
                    inOut.setUnit(record.get("计量单位"));
                }
                
                // 处理数值类型字段
                inOut.setInQuantity(parseBigDecimal(record.get("入库数量")));
                inOut.setInAmountWithTax(parseBigDecimal(record.get("入库含税金额")));
                inOut.setInAmountWithoutTax(parseBigDecimal(record.get("入库不含税金额")));
                inOut.setTotalTax(parseBigDecimal(record.get("总税额")));
                inOut.setUnitPriceWithTax(parseBigDecimal(record.get("含税单价")));
                inOut.setUnitPriceWithoutTax(parseBigDecimal(record.get("不含税单价")));
                inOut.setTax(parseBigDecimal(record.get("税额")));
                if (StringUtils.hasText(record.get("进货税率"))) {
                    inOut.setPurchaseTaxRate(record.get("进货税率"));
                }
                
                if (StringUtils.hasText(record.get("供应商"))) {
                    inOut.setSupplier(record.get("供应商"));
                }
                // 操作员,操作员工号,供应商编码,仓库名称,仓库编码
                if (StringUtils.hasText(record.get("操作员"))) {
                    inOut.setOperator(record.get("操作员"));
                }
                if (StringUtils.hasText(record.get("操作员工号"))) {
                    inOut.setOperatorEmployeeNo(record.get("操作员工号"));
                }
                if (StringUtils.hasText(record.get("供应商编码"))) {
                    inOut.setSupplierCode(record.get("供应商编码"));
                }
                if (StringUtils.hasText(record.get("仓库名称"))) {
                    inOut.setWarehouseName(record.get("仓库名称"));
                }
                if (StringUtils.hasText(record.get("仓库编码"))) {
                    inOut.setWarehouseCode(record.get("仓库编码"));
                }
                
                // 处理新增字段
                if (StringUtils.hasText(record.get("采购协议名称"))) {
                    inOut.setPurchaseAgreementName(record.get("采购协议名称"));
                }
                if (StringUtils.hasText(record.get("返货单编码"))) {
                    inOut.setReturnOrderCode(record.get("返货单编码"));
                }
                
                // 处理返货单审批通过时间
                String returnApprovalTimeStr = record.get("返货单审批通过时间");
                if (StringUtils.hasText(returnApprovalTimeStr)) {
                    try {
                        inOut.setReturnApprovalTime(LocalDateTime.parse(returnApprovalTimeStr, DATE_TIME_FORMATTER));
                    } catch (Exception e) {
                        log.warn("Invalid return approval time format: {}", returnApprovalTimeStr);
                    }
                }
                
                // 处理返货时间
                String returnTimeStr = record.get("返货时间");
                if (StringUtils.hasText(returnTimeStr)) {
                    try {
                        inOut.setReturnTime(LocalDateTime.parse(returnTimeStr, DATE_TIME_FORMATTER));
                    } catch (Exception e) {
                        log.warn("Invalid return time format: {}", returnTimeStr);
                    }
                }
                
                if (StringUtils.hasText(record.get("一级分类"))) {
                    inOut.setFirstCategory(record.get("一级分类"));
                }
                if (StringUtils.hasText(record.get("供应商外部编码"))) {
                    inOut.setSupplierExternalCode(record.get("供应商外部编码"));
                }
                
                inOut.setSearchDate(searchDate);
                
                inOutList.add(inOut);
            } catch (Exception e) {
                log.error("Error processing C08 record: {}", record, e);
                throw new RuntimeException("Failed to process C08 record", e);
            }
        }

        // 5. 保存数据
        try {
            saveBatch(inOutList);
            log.info("Successfully saved {} C08 records for date {}", inOutList.size(), searchDate);
            return inOutList.size();
        } catch (Exception e) {
            log.error("Error saving C08 data batch", e);
            throw new RuntimeException("Failed to save C08 data batch", e);
        }
    }

    /**
     * 解析BigDecimal类型
     * @param value 字符串值
     * @return BigDecimal对象，如果解析失败返回null
     */
    private BigDecimal parseBigDecimal(String value) {
        if (!StringUtils.hasText(value)) {
            return null;
        }
        try {
            return new BigDecimal(value.trim());
        } catch (NumberFormatException e) {
            log.warn("Failed to parse BigDecimal value: {}", value);
            return null;
        }
    }
} 